﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
using intelliPaper.Model;
using System.Linq;
using intelliPaper.FileHandler;
using intelliPaper.DB;
using System.Xml.Serialization;
using intelliSys.Management.Automation.Test.Properties;
using System.Diagnostics;
using System.IO;

namespace intelliSys.Management.Automation.Test
{
    /// <summary>
    /// Interaction logic for TestPaper.xaml
    /// </summary>
    public partial class TestPaper : Window
    {
        Storyboard shrink;
        Storyboard expand;
        public TestPaper()
        {
            this.InitializeComponent();
            if (Settings.Default.MPDHistory == null)
            {
                Settings.Default.MPDHistory = new System.Collections.ArrayList();
            }


            this.MouseLeftButtonDown += new MouseButtonEventHandler(TestPaper_MouseLeftButtonDown);
            this.Loaded += new RoutedEventHandler(QuestionMgmt_Loaded);
            CommandType = WindowCommandType._UNSPECIFIED_;
            // Insert code required on object creation below this point.
        }
        static ValidationLogic[] validationLogics;
        static TestPaper()
        {
            validationLogics = new ValidationLogic[]
            {
                new ValidationLogic()
                {
                    PreventContinue = true,
                     Detail = "测试时间为空或格式错误",
                     Summary = "错误域格式"
                },
                new ValidationLogic()
                {
                    PreventContinue = true,
                    Detail = "描述为空",
                    Summary = "空域"
                },
                new ValidationLogic()
                {
                    PreventContinue=true,
                    Detail = "选择题数目不可为空或非法字符",
                    Summary = "无效格式或空域"
                },
                 new ValidationLogic()
                {
                    PreventContinue=true,
                    Detail = "填空题数目不可为空或非法字符",
                    Summary = "无效格式或空域"
                },
                 new ValidationLogic()
                {
                    PreventContinue=true,
                    Detail = "判断题数目不可为空或非法字符",
                    Summary = "无效格式或空域"
                },
                 new ValidationLogic()
                {
                    PreventContinue=true,
                    Detail = "其他题数目不可为空或非法字符",
                    Summary = "无效格式或空域"
                },
                new ValidationLogic()
                {
                    PreventContinue=true,
                    Detail = "试卷中题量为0",
                    Summary = "无效域"
                }
            };
            validationLogics[0].ValidateMethod = new ValidationLogic.Validate(ValidationLogic.DateTimeFormatLogic);
            validationLogics[1].ValidateMethod = new ValidationLogic.Validate(ValidationLogic.Non_EmptyLogic);
            validationLogics[2].ValidateMethod = validationLogics[3].ValidateMethod = validationLogics[4].ValidateMethod = validationLogics[5].ValidateMethod = new ValidationLogic.Validate(ValidationLogic.IntValidityLogic);
            validationLogics[6].ValidateMethod = new ValidationLogic.Validate(ValidationLogic.ListBoxEmptyLogic);
        }
        public WindowCommandType CommandType
        {
            get;
            set;
        }
        public WindowCommandResult DialogueResult
        {
            get
            {
                return dialogueResult;
            }
        }
        WindowCommandResult dialogueResult = WindowCommandResult._UNSPECIFIED_;
        void GenerateDocView(object sender, RoutedEventArgs e)
        {

            var paper = this.DataContext as Paper;
            if (Automatic.IsChecked.Value)
            {
                RefreshStatistics();
                return;
            }
            if (paper != null)
            {
                if (paper.Questions.Count == 0)
                {
                    Message.Show(this, "错误", MessageType.Comfirm, "在生成预览之前，必须为该试卷增加试题", "生成预览");
                    return;
                }
            }
            else
            {
                Message.Show(this, "开发错误", MessageType.Comfirm, "在生成预览之前，TestPaper页面必须设置DataContext", "开发人员-生成预览");
                return;
            }
            WordGenerationTask wordGenerationTask = new WordGenerationTask();
            wordGenerationTask.Settings = new WordGenerationTask.PageSettingsViewModel()
            {
                Footer = enableAutoFootNote.IsChecked.Value ? "_USEDEFAULT_" : BdyText5.Text,
                Header = header.Text,
                PaperSize = paperSizeChooser.SelectedItem.ToString(),
                Orientation = orientationChooser.SelectedItem.ToString()
            };
            System.Threading.ThreadPool.QueueUserWorkItem(o =>
            {
                wordGenerationTask.MergeFile(paper.Questions.ToArray());
                this.Dispatcher.Invoke(new Action(() =>
                    {
                        Message.ShutdownWaitingCurrent();
                    }));
                if (wordGenerationTask.exception != null)
                {
                    this.Dispatcher.Invoke(new Action(() =>
                        {
                            Message.Show(this, "错误", MessageType.Comfirm, "发生了一个错误:\n" + wordGenerationTask.exception.Message, "生成预览");
                        }));
                    return;
                }
            });
            Message.Show(this, "请稍后", MessageType.Wait, "", "生成预览");
        }
        void TestPaper_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (Cursor == Cursors.Help)
            {
                if (e.OriginalSource is Run)
                    Message.Show(this, "Help System", MessageType.Comfirm, "[CDATA] IS NULL", "关于" + (e.OriginalSource as Run).Text + "的帮助");
                else if (e.OriginalSource is TextBlock)
                    Message.Show(this, "Help System", MessageType.Comfirm, "[CDATA] IS NULL", "关于" + (e.OriginalSource as TextBlock).Text + "的帮助");
                else
                    Message.Show(this, "Help System", MessageType.Comfirm, "您的鼠标未落在帮助点上。通常，帮助点是显示在程序中的文字，它们不包含在以下内容中\n1)文本框\n2)按钮", "无法找到类型为" + e.OriginalSource.GetType().Name + "的帮助");
                return;
            }
            this.DragMove();
        }

        void QuestionMgmt_Loaded(object sender, RoutedEventArgs e)
        {
            shrink = Resources["Shrink"] as Storyboard;
            expand = Resources["Expand"] as Storyboard;
            validationLogics[0].FrameworkElement = BdyText1;
            validationLogics[1].FrameworkElement = BdyText;
            validationLogics[2].FrameworkElement = MultipleChoicesCount;
            validationLogics[3].FrameworkElement = TrueOrFalseCount;
            validationLogics[4].FrameworkElement = BlankFillingCount;
            validationLogics[5].FrameworkElement = OthersCount;
            validationLogics[6].FrameworkElement = QuestionList;
            Automatic.IsEnabled = CommandType != WindowCommandType.Open;
            InitialMPDHistory();
            try
            {
                RefreshStatistics();
                KnowledgePointsRefresh();
            }
            catch
            {
            }
        }

        ContextMenu MPDContextMenu = new ContextMenu();

        ListBoxItem GetHistoyListBoxItem(string s)
        {
            ListBoxItem lbi = new ListBoxItem();
            lbi.Content = s.Split('\\').Last().Split('$').First();
            lbi.Background = null;
            lbi.ContextMenu = Resources["MPDHistory"] as ContextMenu;
            ToolTip t = new System.Windows.Controls.ToolTip();
            t.Background = null;
            t.Foreground = new SolidColorBrush(Colors.White);
            t.Content = s.Split('$').First() + "   最后使用时间 :" + s.Split('$').Last();
            lbi.ToolTip = t;
            return lbi;
        }

        void InitialMPDHistory()
        {
            Array historyList = Settings.Default.MPDHistory.ToArray(typeof(string));

            foreach (string s in historyList)
            {
                //lbxMPDHistory.Items.Add(s);


                lbxMPDHistory.Items.Add(GetHistoyListBoxItem(s));
                //Label l = new Label();
                //Run r = new Run(s.Split('\\').Last());
                //Hyperlink h = new Hyperlink(r);
                //h.NavigateUri = new Uri(s, UriKind.Absolute);
                //l.Content = h;
                //h.Click += new RoutedEventHandler(h_Click);
                //spnlMPDHistory.Children.Add(l);
            }
        }

        void h_Click(object sender, RoutedEventArgs e)
        {
            Hyperlink h = sender as Hyperlink;

            if (File.Exists(h.NavigateUri.LocalPath))
            {
                //Process.Start(h.NavigateUri.LocalPath );
                Paper p = MPDHandler.ReadFromMPDFile(h.NavigateUri.LocalPath);
                var localCpy = p.Questions;
                Helper.FillQuestions(DataRepository.Questions,  localCpy);

                this.DataContext = p;
            }
            else
            {
                Message.Show(this, "打开", MessageType.Comfirm, "您所打开的文件不存在，可能您已经将它移动或者删除，请确认路径，或者打开其他文件", "打开失败，文件不存在");
                Settings.Default.MPDHistory.Remove(h.NavigateUri.LocalPath);
            }

            //throw new NotImplementedException();
        }
        private void lbxMPDHistory_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            try
            {
                if (File.Exists(Settings.Default.MPDHistory[lbxMPDHistory.SelectedIndex].ToString().Split('$').First()))
                {
                    Paper p = MPDHandler.ReadFromMPDFile(Settings.Default.MPDHistory[lbxMPDHistory.SelectedIndex].ToString().Split('$').First());
                    var localCpy = p.Questions;
                    Helper.FillQuestions(DataRepository.Questions, localCpy);

                    this.DataContext = p;
                    tabCtrl.SelectedIndex = 0;
                    RefreshStatistics();
                }
                else
                {
                    if (Message.Show(this, "打开", MessageType.Comfirm | MessageType.Cancel, "您所打开的文件不存在，可能您已经将它移动或者删除，请确认路径，或者打开其他文件。需要删除此记录么？", "打开失败，文件不存在") == MessageType.Comfirm)
                    {
                        Settings.Default.MPDHistory.RemoveAt(lbxMPDHistory.SelectedIndex);
                        lbxMPDHistory.Items.RemoveAt(lbxMPDHistory.SelectedIndex);
                        Settings.Default.Save();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException();
            }
        }
        Grid lastFocus;
        private void Grid_GotFocus(object sender, RoutedEventArgs e)
        {
            if ((sender as Grid) == lastFocus)
            {
                lastFocus = sender as Grid;
                return;
            }
            else
                lastFocus = sender as Grid;
            (expand.Children[0] as DoubleAnimationUsingKeyFrames).KeyFrames[1].Value = groupBox1.ActualHeight - 300;
            expand.Begin(sender as FrameworkElement);
        }

        private void Grid_LostFocus(object sender, RoutedEventArgs e)
        {
            if ((sender as Grid) != lastFocus)
            {
                lastFocus = sender as Grid;
                return;
            }
            else
                lastFocus = null;
            (shrink.Children[0] as DoubleAnimationUsingKeyFrames).KeyFrames[0].Value = groupBox1.ActualHeight - 300;
            shrink.Begin(sender as FrameworkElement);
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Button butt = sender as Button;
            if (butt.Content.ToString() == "展开")
            {
                butt.Content = "收起";
                (expand.Children[0] as DoubleAnimationUsingKeyFrames).KeyFrames[1].Value = groupBox1.ActualHeight - 330;
                expand.Begin(butt.Parent as Grid);
            }
            else
            {
                butt.Content = "展开";
                (shrink.Children[0] as DoubleAnimationUsingKeyFrames).KeyFrames[0].Value = groupBox1.ActualHeight - 330;
                shrink.Begin(butt.Parent as Grid);
            }
        }

        private void QuestionList_Add_Click(object sender, RoutedEventArgs e)
        {
            GenericList gl = new GenericList();
            gl.commandBox.SelectedIndex = 0;
            gl.commandBox.IsEnabled = false;
            gl.ListSelectionMode = SelectionMode.Extended;
            gl.ShowDialog();
            if (gl.DialogueResult == null)
            {
                return;
            }
            Paper dtctx = this.DataContext as Paper;
            var questions = (gl.DialogueResult as System.Collections.IList).Cast<Question>();
            foreach (Question q in questions)
            {
                if (dtctx.Questions.Any<Question>(o =>
                    {
                        return o.ID == q.ID;
                    }))
                {
                    Message.Show(this, "重复值", MessageType.Comfirm, "试题中已经含有该值。\n重复的值不会被重复添加。", "检测到重复的值");
                    continue;
                }
                else
                {
                    dtctx.Questions.Add(q);
                }
            }
            QuestionList.Items.Refresh();
            KnowledgePointsRefresh();
            RefreshStatistics();
        }
        public void RefreshStatistics()
        {
            var pp = this.DataContext as Paper;
            MultipleChoicesCount.Text = pp.Questions.Count<Question>(o =>
                {
                    return o.QuestionType == "选择题";
                }).ToString();
            TrueOrFalseCount.Text = pp.Questions.Count<Question>(o =>
            {
                return o.QuestionType == "判断题";
            }).ToString();
            BlankFillingCount.Text = pp.Questions.Count<Question>(o =>
            {
                return o.QuestionType == "填空题";
            }).ToString();
            OthersCount.Text = pp.Questions.Count<Question>(o =>
            {
                return o.QuestionType == "其他题";
            }).ToString();
            try
            {
                Difficulty.Text = pp.Questions.Average<Question>(o =>
                    {
                        return o.StartDifficulty;
                    }).ToString();
            }
            catch
            {
                Difficulty.Text = "不可用";
            }
        }
        private void KnowledgePointsRefresh()
        {
            KnowledgePointsList.ItemsSource = (this.DataContext as Paper).KnowledgePoints = (this.DataContext as Paper).Questions.SelectMany<Question, KnowledgePoint>(o =>
                  {
                      return o.KnowledgePoints;
                  }).Distinct().ToList();
        }

        private void QuestionList_Remove_Click(object sender, RoutedEventArgs e)
        {
            if (AskForListViewSelectionIfUnselected(QuestionList))
            {
                (tabCtrl.DataContext as intelliPaper.Model.Paper).Questions.Remove(QuestionList.SelectedItem as intelliPaper.Model.Question);
                QuestionList.Items.Refresh();
                KnowledgePointsRefresh();
                RefreshStatistics();
            }
        }
        private bool AskForListViewSelectionIfUnselected(ListBox lstvw)
        {
            if (lstvw.SelectedItem == null)
            {
                Message.Show(this, "No Item Selected", MessageType.Comfirm, "必须选择一项以便继续", "未选择内容");
                return false;
            }
            return true;
        }
        private void OnSiteHelp_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {

        }

        private void OnSiteHelp_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            var HelpEnabled = Cursor == Cursors.Help;
            if (HelpEnabled)
            {
                HelpIndicator.Text = "已关闭OnSite帮助";
                Cursor = Cursors.Arrow;
            }
            else
            {
                HelpIndicator.Text = "已开启OnSite帮助";
                Cursor = Cursors.Help;
            }
            // TODO: Add event handler implementation here.
        }

        private void Comfirm_Click(object sender, RoutedEventArgs e)
        {
            CheckList.Items.Clear();
            int warning = 0;
            foreach (var validate in validationLogics)
            {
                if (!validate.ValidateMethod(validate.FrameworkElement))
                {
                    CheckList.Items.Add(validate);
                    if (!validate.PreventContinue)
                    {
                        warning++;
                    }
                }
            }
            if (CheckList.Items.Count - warning != 0)
            {
                Message.Show(this, "验证错误", MessageType.Comfirm, "此页存在一个或多个验证错误，在继续之前，您必须更正它们。\n通常，验证框出现在上一屏幕的左下角。", "验证错误阻止继续进行");
                return;
            }
            if (warning != 0)
            {
                var result = Message.Show(this, "验证错误", MessageType.Comfirm | MessageType.Cancel, "此页存在一个或多个验证警告，在继续之前，建议您更正它们。\n通常，验证框出现在上一屏幕的左下角。\n单击确定以继续，取消以返回", "验证警告可能导致意外后果");
                if (result != MessageType.Comfirm)
                {
                    return;
                }
            }
            //if (Message.Show(this, "CONFIRMINATION", MessageType.Comfirm | MessageType.Cancel, "This action will perform a data base write even if no properties are changed.\nWould you like to continue?", "ABOUT TO WRITE TO DATABASE") != MessageType.Comfirm)
            //{
            //    return;
            //}
            if (CommandType == WindowCommandType.CreateNew)
            {
                dialogueResult = WindowCommandResult.CreateNewSavingChanges;
            }
            else
            {
                dialogueResult = WindowCommandResult.OpenSavingChanges;
            }
            this.Close();
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            if (CommandType == WindowCommandType.Open)
            {
                dialogueResult = WindowCommandResult.OpenDiscardingChanges;
            }
            else
            {
                dialogueResult = WindowCommandResult.CreateNewDiscardingChanges;
            }
            this.Close();
        }

        private void CheckList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var item = CheckList.SelectedItem;
            if (item == null)
                return;
            var current = (item as ValidationLogic).FrameworkElement;
            while (current.Parent.GetType() != typeof(TabItem))
            {
                current = current.Parent as FrameworkElement;
            }
            if (current != null)
            {
                (current.Parent as TabItem).IsSelected = true;
            }
            (item as ValidationLogic).FrameworkElement.Focus();
        }

        private void Automatic_Checked(object sender, RoutedEventArgs e)
        {
            if (Automatic.IsChecked.Value)
            {
                (this.DataContext as Paper).Questions.Clear();
                QuestionCtrlGrid.IsHitTestVisible = false;
                KnowledgePointCtrlGrid.IsHitTestVisible = true;
                StatisticCtrlControlGrid.IsHitTestVisible = true;
            }
            else
            {
                QuestionCtrlGrid.IsHitTestVisible = true;
                KnowledgePointCtrlGrid.IsHitTestVisible = false;
                StatisticCtrlControlGrid.IsHitTestVisible = false;
            }
        }

        private void KnowledgePoint_Add_Click(object sender, RoutedEventArgs e)
        {
            GenericList gl = new GenericList();
            gl.commandBox.SelectedIndex = 2;
            gl.commandBox.IsEnabled = false;
            gl.ListSelectionMode = SelectionMode.Extended;
            gl.ShowDialog();
            if (gl.DialogueResult == null)
            {
                return;
            }
            var knowledgePts = (gl.DialogueResult as System.Collections.IList).Cast<KnowledgePoint>();
            Paper dtctx = this.DataContext as Paper;
            foreach (KnowledgePoint kp in knowledgePts)
            {
                if (dtctx.KnowledgePoints.Any<KnowledgePoint>(o =>
                {
                    return o.ID == kp.ID;
                }))
                {
                    Message.Show(this, "重复值", MessageType.Comfirm, "知识点中已经含有该值。\n重复的值不会被重复添加。", "检测到重复的值");
                    continue;
                }
                else
                {
                    dtctx.KnowledgePoints.Add(kp);
                }
            }
            KnowledgePointsList.Items.Refresh();
        }

        private void KnowledgePoint_Remove_Click(object sender, RoutedEventArgs e)
        {
            if (AskForListViewSelectionIfUnselected(KnowledgePointsList))
            {
                (tabCtrl.DataContext as intelliPaper.Model.Question).KnowledgePoints.Remove(KnowledgePointsList.SelectedItem as intelliPaper.Model.KnowledgePoint);
                KnowledgePointsList.Items.Refresh();
            }
        }

        private void btnSave_Click(object sender, System.Windows.RoutedEventArgs e)
        {

            string strPath = Environment.CurrentDirectory;
            Microsoft.Win32.SaveFileDialog saveFileDialog = new Microsoft.Win32.SaveFileDialog();
            saveFileDialog.DefaultExt = "mpd";
            saveFileDialog.AddExtension = true;
            saveFileDialog.Filter = ".mpd|.mpd";
            saveFileDialog.OverwritePrompt = true;
            saveFileDialog.FileName = "新试卷";
            saveFileDialog.CheckPathExists = true;
            saveFileDialog.Title = "保存组卷文件";

            bool? b = saveFileDialog.ShowDialog();

            if (b == true)
            {
                if (intelliPaper.FileHandler.MPDHandler.WriteToMPDFile(this.DataContext as Paper, saveFileDialog.FileName))
                {
                    Settings.Default.MPDHistory.Add(saveFileDialog.FileName + "$" + DateTime.Now);
                    Settings.Default.Save();
                    Message.Show(this, "管理", MessageType.Comfirm, "\n您的组卷文档已经成功保存，您可以在资源管理器中找到并管理，但这个文档只能在您的电脑上使用", "保存成功 !");
                }
                else
                {
                    Message.Show(this, "管理", MessageType.Comfirm, "\n您的组卷文档没有成功保存，请查看帮助文档，或者联系我们", "失败了诶...");
                }
            }

            Environment.CurrentDirectory = strPath;
            // TODO: Add event handler implementation here.
        }

        private void btnOpen_Click(object sender, System.Windows.RoutedEventArgs e)
        {

            Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
            openFileDialog.Title = "打开组卷文件";
            openFileDialog.DefaultExt = ".mpd|.mpd";
            openFileDialog.DereferenceLinks = true;

            bool? b = openFileDialog.ShowDialog();

            if (b == true)
            {
                Paper paperInFile = MPDHandler.ReadFromMPDFile(openFileDialog.FileName);
                var localCpy = paperInFile.Questions;
                Helper.FillQuestions(DataRepository.Questions, localCpy);
                this.DataContext = paperInFile;
                RefreshStatistics();
                int i;
                for (i = 0; i < Settings.Default.MPDHistory.Count; i++)
                {
                    string s = Settings.Default.MPDHistory[i].ToString();
                    if (s.StartsWith(openFileDialog.FileName))
                    {
                        Settings.Default.MPDHistory[i] = openFileDialog.FileName + "$" + DateTime.Now;
                        break;
                    }
                }
                if (i == Settings.Default.MPDHistory.Count)
                {
                    Settings.Default.MPDHistory.Add(openFileDialog.FileName + "$" + DateTime.Now);
                    lbxMPDHistory.Items.Add(GetHistoyListBoxItem(openFileDialog.FileName + "$" + DateTime.Now));
                }


                Settings.Default.Save();
                tabCtrl.SelectedIndex = 0;
            }

            // TODO: Add event handler implementation here.
        }



        private void menuitemDelele_Click(object sender, RoutedEventArgs e)
        {
            ListBoxItem lbi = (ListBoxItem)ContextMenuService.GetPlacementTarget(LogicalTreeHelper.GetParent(sender as MenuItem));
            Settings.Default.MPDHistory.RemoveAt(lbxMPDHistory.Items.IndexOf(lbi));
            lbxMPDHistory.Items.Remove(lbi);
            Settings.Default.Save();
        }


        //private bool AskForListViewSelectionIfUnselected(ListBox lstvw)
        //{
        //    if (lstvw.SelectedItem == null)
        //    {
        //        Message.Show(this, "No Item Selected", MessageType.Comfirm, "必须选择一项以便继续", "未选择内容");
        //        return false;
        //    }
        //    return true;
        //}
    }
}